package ca.mcgill.mni.bic;

import java.util.List;

import org.apache.log4j.Logger;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;

public class QcToolMainWindow {
	
	private StudyInfoWidget studyInfo;
	private SeriesInfoWidget seriesInfo;

	private TarchiveDatabase tarDb;
	
	private Composite infoPane;
	private Shell shell;
	private Tree tree;
	private Display display;
	
	private List<StudyListing> studies;
	private Color invalidLabelColor;
	private Color validUnsentColor;
	private Color queuedColor;
	
	private String currentFilterSite;
	private boolean currentFilterHideReviewed;
	private boolean currentFilterHideSent;
	private String currentFilterPatientName;
	
	static Logger logger = Logger.getLogger(QcToolMainWindow.class);
	
	/**
	 * @param args
	 */
	public QcToolMainWindow(TarchiveDatabase tarDb) {

		this.tarDb = tarDb;
		
		display = Display.getCurrent();
		if(display == null)
			display = new Display();
		shell = new Shell(display);
		FillLayout layout = new FillLayout(SWT.HORIZONTAL);
		layout.spacing = 5;
		shell.setLayout(layout);
		shell.setText("QcTool");
		
		invalidLabelColor = display.getSystemColor(SWT.COLOR_RED);
		validUnsentColor = display.getSystemColor(SWT.COLOR_DARK_GREEN);
		queuedColor = display.getSystemColor(SWT.COLOR_DARK_YELLOW);
		
		// create the menu bar and menus
		createMenu();
		
		// create the info panel
		infoPane = new Composite(shell, SWT.NONE);

		// create the study tree
		createStudyTree();
		
		// initially populate the study tree with all studies
		filterStudies(null, false, false, null);
		
		// main loop
		shell.open();
		while(!shell.isDisposed()){
			if(!display.readAndDispatch())
				display.sleep();
		}
		display.dispose();
	}
	
	public void reloadStudies() {
		logger.debug("Reloading studies for listing");
		filterStudies(currentFilterSite, currentFilterHideReviewed, currentFilterHideSent, currentFilterPatientName);
	}
	
	public void filterStudies(String site, Boolean hideReviewed, Boolean hideSent, String patientName) {
		currentFilterSite = site;
		currentFilterHideReviewed = hideReviewed;
		currentFilterHideSent = hideSent;
		currentFilterPatientName = patientName;
		
		tree.clearAll(true);
		studies = tarDb.getListOfStudies(site, hideReviewed, hideSent, patientName);
		tree.setItemCount(studies.size());
	}
	
	private void showStudy(Study study) {
		if(infoPane != null) {
			infoPane.dispose();
			infoPane = null;
		}
		
		logger.debug("Showing study pane for TarchiveID " + study.tarchiveID);
		
		infoPane = new Composite(shell, SWT.NONE);
		infoPane.setLayout(new FillLayout(SWT.VERTICAL));
		
		studyInfo = new StudyInfoWidget(infoPane, SWT.NONE);
		studyInfo.setStudy(study);
		shell.layout();
	}
	
	private void showSeries(Series series) {
		if(infoPane != null) {
			infoPane.dispose();
			infoPane = null;
		}
		
		logger.debug("Showing series pane for TarchiveID " + series.parentStudy.tarchiveID + " series " + series.seriesNumber +  " (" + series.seriesDescription + ")");
		
		infoPane = new Composite(shell, SWT.NONE);
		infoPane.setLayout(new FillLayout(SWT.VERTICAL));
		
		seriesInfo = new SeriesInfoWidget(infoPane, SWT.NONE);
		seriesInfo.setSeries(series);
		shell.layout();
	}
	
	private void showAbout() {
		MessageBox about = new MessageBox(shell, SWT.ICON_INFORMATION);
		about.setMessage("QcTool 1.0\n\n" +
				"Jonathan Harlap\n" +
				"jharlap@bic.mni.mcgill.ca\n" +
				"(c) 2006");
		about.setText("About QcTool");
		about.open();
	}
	
	private void createMenu() {
		Menu menu = new Menu(shell, SWT.BAR);
		shell.setMenuBar(menu);
		
		// file menu
		MenuItem file = new MenuItem(menu, SWT.CASCADE);
		file.setText("File");
		
		Menu filemenu = new Menu(shell, SWT.DROP_DOWN);
		file.setMenu(filemenu);
		
		// reload item
		MenuItem reload = new MenuItem(filemenu, SWT.PUSH);
		reload.setText("&Reload\tCtrl+R");
		reload.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event event) {
				reloadStudies();
			}
		});
		reload.setAccelerator(SWT.CTRL+'R');
		
		// quit item
		MenuItem quit = new MenuItem(filemenu, SWT.PUSH);
		quit.setText("&Quit\tCtrl+Q");
		quit.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event event) {
				shell.dispose();
			}
		});
		quit.setAccelerator(SWT.CTRL+'Q');
		
		// filter menu
		MenuItem filter = new MenuItem(menu, SWT.CASCADE);
		filter.setText("Filter");
		
		Menu filtermenu = new Menu(shell, SWT.DROP_DOWN);
		filter.setMenu(filtermenu);
		
		MenuItem allStudiesFilter = new MenuItem(filtermenu, SWT.PUSH);
		allStudiesFilter.setText("&All studies\tCtrl+A");
		allStudiesFilter.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event event) {
				filterStudies(null, false, false, null);
			}
		});
		allStudiesFilter.setAccelerator(SWT.CTRL+'A');
		
		MenuItem unsentStudiesFilter = new MenuItem(filtermenu, SWT.PUSH);
		unsentStudiesFilter.setText("Un&sent studies\tCtrl+S");
		unsentStudiesFilter.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event event) {
				filterStudies(null, false, true, null);
			}
		});
		unsentStudiesFilter.setAccelerator(SWT.CTRL+'S');
		
		MenuItem unreviewedStudiesFilter = new MenuItem(filtermenu, SWT.PUSH);
		unreviewedStudiesFilter.setText("Un&reviewed studies\tCtrl+R");
		unreviewedStudiesFilter.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event event) {
				filterStudies(null, true, true, null);
			}
		});
		unreviewedStudiesFilter.setAccelerator(SWT.CTRL+'R');
		
		MenuItem patientNameFilter = new MenuItem(filtermenu, SWT.PUSH);
		patientNameFilter.setText("Only specific &patient name\tCtrl+P");
		patientNameFilter.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event event) {
				InputDialog input = new InputDialog(shell);
				String patientName = input.open("Patient name starts with (use % as wildcard):");
				filterStudies(null, false, false, patientName);
			}
		});
		patientNameFilter.setAccelerator(SWT.CTRL+'P');
		
		MenuItem help = new MenuItem(menu, SWT.CASCADE | SWT.RIGHT);
		help.setText("Help");
		
		Menu helpmenu = new Menu(shell, SWT.DROP_DOWN);
		help.setMenu(helpmenu);
		
		MenuItem about = new MenuItem(helpmenu, SWT.PUSH);
		about.setText("About");
		about.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event event) {
				showAbout();
			}
		});
	}
	
	private void createStudyTree() {
		tree = new Tree(shell, SWT.VIRTUAL | SWT.BORDER);
		tree.addListener(SWT.SetData, new Listener() {
			public void handleEvent(Event event) {
				TreeItem item = (TreeItem)event.item;
				TreeItem parentItem = item.getParentItem();
				String text = null;
				
				if (parentItem == null) {
					StudyListing study = studies.get(tree.indexOf(item));
					item.setItemCount(1);
					text = study.getLabel();
					if(study.pendingTransfer()) {
						item.setForeground(queuedColor);
					} else {
						if(Study.isValidPatientName(study.patientName)) {
							if(study.wasSent()) {
								item.setForeground(null);
							} else {
								item.setForeground(validUnsentColor);
							}
						} else {
							item.setForeground(invalidLabelColor);
						}
					}
				} else {
					Study parentStudy = studies.get(tree.indexOf(parentItem)).getStudy();
					parentItem.setItemCount(parentStudy.series.size());
					Series series = parentStudy.series.get(parentItem.indexOf(item));
					text = series.getLabel();
					if(Series.isValidDescription(series.seriesDescription))
						item.setForeground(null);
					else
						item.setForeground(invalidLabelColor);
				}
				item.setText(text);
			}
		});
		
		tree.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent event) {
				TreeItem item = (TreeItem) event.item;
				TreeItem parentItem = item.getParentItem();
				if (parentItem == null) {
//					 update the study info pane
					showStudy(studies.get(tree.indexOf(item)).getStudy());
				} else {
					// update the series info pane
					showSeries(studies.get(tree.indexOf(parentItem)).getStudy().series.get(parentItem.indexOf(item)));
				}
				
			}

			public void widgetDefaultSelected(SelectionEvent arg0) {
				// TODO Auto-generated method stub
				
			}
		});
		
		
	}
}
